Digital computer operating systems periodically schedule processes for the central processing unit (CPU) of the computer to perform. The operating system schedules sub-parts of executable applications, known as threads, on the CPU. In multi-tasking operating systems, threads can be independently scheduled for execution on the processor so that more than one computer program or application may proceed at the same time. While the CPU only works on one thread at a time, it appears to the user that the CPU is running multiple applications concurrently. During multi-tasking, the CPU interrupts execution of one thread to begin execution of another thread or to resume execution of a previously interrupted thread. Switching from one thread to another is known as a “context switch.”
One multi-tasking operating system currently available is the “WINDOWS CE” operating system developed by Microsoft Corporation. “WINDOWS CE”  supports a wide variety of CPUs. Many of these CPUs do not provide full 32-bit addressing on the external pins of the device. This presents a problem in that many of today's computer systems utilize fast I/O devices with high-speed 32-bit buses, such as the industry standard peripheral component interconnect (PCI) bus. PCI devices, such as video controllers, are assigned a range of contiguous addresses on the bus through which they may be accessed.
To enable access to several PCI devices, each PCI device is assigned a unique, non-overlapping address range, whereby the high order bits of the 32-bit address are used to distinguish among address spaces for different devices. For instance, the upper two bits of a 28-bit address might be used to differentiate between four different PCI devices, with the remaining 26 bits being used for addressing within the devices themselves. Unfortunately, the CPU itself may not support 28 bits, but only 26 bits. Accordingly, there is no way for the CPU to distinguish amongst the different PCI devices on the bus. When a CPU is incapable of providing the full 32-bit PCI address space, there is a need to extend the addressing output of the CPU to properly access a PCI device connected to a PCI bus.
Special chips, referred to as “PCI host bridges,” are available to interface a CPU to a PCI bus. Some of these chips have circuitry for extending the limited address range of CPUs such as those discussed above.
FIG. 1 shows a system utilizing a PCI host bridge. The system includes a prior art computer 10 having a microprocessor 12 coupled to a PCI host bridge 14. The microprocessor 12 has a central processing unit (CPU) 16. The CPU 14 is connected to multiple devices, such as a PCMCIA driver 18, a universal serial bus (USB) 20, an I/O (input/output) port 22, and a bus interface unit (BIU) 24, via an address bus 26. The BUI 24 interfaces the microprocessor 12 to the PCI host bridge 14 via a standard address bus 30 having less than thirty-two lines. The PCI host bridge 14 converts addresses received from the address bus 30 to full 32-bit addresses output over a 32-bit PCI bus 32. One or more PCI devices are coupled to the PCI bus 32, as represented by devices 34a, 34b, and 34c. 
The PCI host bridge 14 has an extension register 36 to extend the address on the bus 32 (i.e., less than 32 bits) to a fill 32-bit address suitable for the PCI bus 32. More particularly, the extension register 36 contains memory to store a number of bits which are concatenated with lower-order bits from the standard address bus 30 to produce a full 32-bit address for one of the PCI devices 34.
The extension register 36 is read from and written to by the CPU 16 to allow the CPU to set the value of the high order address bits. By changing the values in the extension register, the CPU 16 is able to address the full address space supported by the PCI bus 32. For example, assume that a CPU 16 outputs a 26-bit address on bus 30. Further assume that one of the PCI devices 34 is a video device that has been assigned an address range of A4000000 through A7FFFFFF (expressed in hexadecimal notation). To address the video device, the CPU 16 writes the binary value 101001 to the extension register 36 to set the upper six bits of the PCI address. The external address pins of the CPU 16 then supply the low order twenty-six bits during normal bus cycle generation. If the CPU is then required to address a different PCI device, the CPU 16 changes the value in the extension register 36 to match the high order address bits of the target PCI device. For example, if the second PCI device is mapped to the address range of A8000000 through ABFFFFFF, the CPU 16 writes binary value 101010 to the extension register 36 and supplies the lower order twenty-six bits of the address during the bus cycle generation.
The procedure operates adequately within a non-multi-tasking environment, but not in a multi-tasking operating system environment. In present multi-tasking systems, the operating systems are designed to work with specific CPUs that only supply an adequate number of address lines, thereby avoiding the problem described above. The operating system may update the extension register once at system initialization and never update it again since the address bits supplied by the extension register are common across all PCI devices. This situation does not pose any problems because the correct address is generated while the PCI device is accessed.
However, consider the situation of a multi-tasking operating system working with CPUs that do not provide a sufficient number of address lines. The process described must be maintained even though the operating system may suspend or resume execution of a particular thread at any given time. This poses some potentially troublesome problems in that the extension register may contain the wrong values as a result of the context switching performed by the multi-tasking operating system.
Suppose, for example, two threads A and B are accessing PCI devices 1 and 2, respectively, via the PCI host bridge. Thread A needs the extension register set to a value “X” to access PCI Device 1 and thread B requires the extension register to have a value “Y” to access PCI Device 2. Table 1 describes the situation.
TABLE 1Inter-process Conflict In A Multi-tasking Operating SystemExtensionRegisterTimeThread AThread BValueT0Extension Register = XXT1Access PCI Device 1XT2Context SwitchXT3Extension Register = YYT4Access PCI Device 2YT5Context SwitchYT6Access PCI Device 1Y
At time T0, thread A requests the CPU to set the extension register to value X. The CPU then accesses PCI device 1 at time T1. At time T2, the operating system performs a context switch and schedules thread B for execution. At time T3, thread B requests the CPU to set the extension register to value Y. The CPU then accesses PCI device 2 at time T4.
Thereafter, the operating system performs another context switch at time T5 to return to thread A for more execution. However, note that the extension register value remains at the value Y (the value for thread B) rather than the value X for thread A. The value in the extension register is not updated at this time because such an update only occurs when a thread—in this case, thread A—is initially called. As a result, when thread A attempts to access PCI device 1 again at time T6, the extension register contains value Y (i.e., the extension value for PCI device 2) and the access attempt fails.
One way to resolve this problem is to disable the context switching in the operating system while a PCI device is being accessed. This, however, could compromise the performance of the operating system since it may result in “jerky” operation of the applications being performed and would adversely affect the illusion of multi-tasking to the user. Additionally, in time-critical, real-time operating systems that are used in critical medical equipment or aircraft flight control systems, it is absolutely necessary to guarantee that context switches will occur within a specific time period. If context switching is disabled for an arbitrary period of time while a PCI device is being accessed in such a system, the time-critical thread may not execute within its allotted time period, thereby causing failure of the critical system.
A better solution to the problem is to provide a way for the operating system to restore the value of the extension register prior to each context switch so that the correct PCI device is accessed by the operating system every time. This solution is accomplished by the present invention.